<template>
  <div class="widget">
    <a-select
      :value="value"
      :disabled="disabled"
      :placeholder="placeholder || t('请选择')"
      :allow-clear="allowClear"
      :show-arrow="false"
      :open="false"
      :size="size"
      style="flex: 1; width: 0"
      :field-names="fieldNames"
      :options="state.options"
      :loading="state.loading"
      :mode="multiple ? 'multiple' : undefined"
      @change="handleChange"
    >
    </a-select>
    <a-button
      type="primary"
      class="pick-btn"
      :size="(size as ButtonProps['size'])"
      @click="popupState.open = true"
    >
      <SelectOutlined />
    </a-button>
  </div>
  <popup-modal
    v-bind="props"
    :keys="multiple ? value as string[] : [value as string]"
    :rows="state.options"
    :open="popupState.open"
    @cancel="popupState.open = false"
    @ok="handleOk"
  >
    <template v-for="name in Object.keys(slots)" #[name]="slotProps">
      <slot :name="name" v-bind="slotProps"></slot>
    </template>
  </popup-modal>
</template>
<script lang="ts" setup>
import { nextTick } from "vue";
import { useI18n } from "vue-i18n";
import { cloneDeep } from "lodash";
import { reactive, watch } from "vue";
import type { PopupSelectProps } from "./typing";
import type { ButtonProps, SelectProps } from "ant-design-vue";
import PopupModal from "./components/popup-modal.vue";
const props = withDefaults(defineProps<PopupSelectProps>(), {
  allowClear: true,
  width: 600,
  size: "middle",
  fieldNames: () => ({ label: "label", value: "value" }),
  defaultParams: () => ({}),
});
const emit = defineEmits(["update:value", "bring"]);
const slots = defineSlots();
const { t } = useI18n();
/**弹窗状态 */
const popupState = reactive({
  open: false,
});
const state = reactive({
  loading: false,
  options: [],
});
/**查询控件回显数据 */
const query = async () => {
  state.loading = true;
  const { success, result } = await props.queryById(props.value);
  state.loading = false;
  if (success) {
    if (result instanceof Array) {
      state.options = result;
    } else {
      state.options = [result];
    }
    handleBring();
  }
};
watch(
  () => props.value,
  (n, o) => {
    if (n && n != o) query();
  },
  { immediate: true }
);
/**更新组件值 */
const handleUpdate = (value: string | string[]) => {
  emit("update:value", value);
  nextTick(handleBring);
};
/**带出 */
const handleBring = () => {
  if (props.multiple) {
    emit("bring", props.value, cloneDeep(state.options));
  } else {
    emit("bring", props.value, props.value ? state.options[0] : null);
  }
};
/**弹窗选择完成 */
const handleOk = (keys: string[], rows: any[]) => {
  state.options = rows;
  handleUpdate(props.multiple ? keys : keys[0]);
};
// 只有删除清除数据会触发
const handleChange: SelectProps["onChange"] = (value: any) => {
  if (props.multiple) {
    handleUpdate(cloneDeep(value) ?? []);
  } else {
    handleUpdate(value ?? null);
  }
  state.options = state.options.filter((f) => {
    const keyValue = f[props.fieldNames.value];
    if (props.value instanceof Array) {
      return props.value.includes(keyValue);
    } else {
      return props.value == keyValue;
    }
  });
};
</script>
<style lang="less" scoped>
.widget {
  width: 100%;
  display: flex;
  :deep(.ant-select-selector) {
    border-radius: @border-radius 0 0 @border-radius;
    border-right: none;
  }
  .pick-btn {
    border-radius: 0 @border-radius @border-radius 0;
  }
}
</style>
